package com.example.demo.java8.stream;

import com.example.demo.entity.Employee;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;

/**
 * @ author  zengqingfa
 * @ created in    2020/2/23  13:58
 */
public class StreamApiTest3 {

    //循环操作 forEach
    @Test
    public void testForeach() {
        List<Employee> employees = Employee.getEmployees();
        employees.stream().forEach(System.out::println);
    }

    //中间操作：帅选和切片
    //过滤  filter
    @Test
    public void testFilter() {
        List<Employee> employees = Employee.getEmployees();

        /**
         *   Employee{id='1001', name='Lily', sex=0, age=33}
         Employee{id='1004', name='Lucy', sex=0, age=24}
         Employee{id='1007', name='比尔盖茨', sex=1, age=45}
         */
        employees.stream().filter(e -> e.getName().length() > 3).forEach(System.out::println);
    }

    //对流中的元素进行收集
    @Test
    public void testCollect() {
        List<Employee> employeeList = Employee.getEmployees().stream().limit(2).collect(toList());
        //[Employee{id='1001', name='Lily', sex=0, age=33}, Employee{id='1002', name='雷军', sex=1, age=23}]
        System.out.println(employeeList);
    }

    //截断  limit
    @Test
    public void testLimit() {
        /**
         * Employee{id='1001', name='Lily', sex=0, age=33}
         Employee{id='1002', name='雷军', sex=1, age=23}
         */
        Employee.getEmployees().stream().limit(2).forEach(System.out::println);
    }

    //跳过元素 skip
    @Test
    public void testSkip() {
        /**
         * Employee{id='1003', name='马化腾', sex=1, age=56}
         Employee{id='1004', name='Lucy', sex=0, age=24}
         Employee{id='1005', name='Tom', sex=1, age=15}
         Employee{id='1006', name='马云', sex=1, age=66}
         Employee{id='1007', name='比尔盖茨', sex=1, age=45}
         */
        Employee.getEmployees().stream().skip(2).forEach(System.out::println);
        System.out.println();
    }

    //对流中的元素进行计数
    @Test
    public void testCount() {
        System.out.println(Employee.getEmployees().stream().count());//7
    }

    //映射  把一个集合中的转换为另一个
    //   <R> Stream<R> map(Function<? super T, ? extends R> mapper);
    @Test
    public void testMap() {
        List<String> list = Arrays.asList("aa", "bb", "cc");
        //AABBCC
        list.stream().map(s -> s.toUpperCase()).forEach(System.out::print);
        System.out.println();

        //获取员工姓名 Lily雷军马化腾LucyTom马云比尔盖茨
        Employee.getEmployees().stream().map(e -> e.getName()).forEach(System.out::print);
        System.out.println();

        // 获取员工姓名长度大于3的员工姓名  LilyLucy比尔盖茨
        Employee.getEmployees().stream().map(e -> e.getName()).filter(s -> s.length() > 3).forEach(System.out::print);
        System.out.println();
    }

    // 将多个Stream连接成一个Stream，这时候不是用新值取代Stream的值，
    // 与map有所区别，这是重新生成一个Stream对象取而代之。
    @Test
    public void testFlatMap() {
        List<List<Employee>> employees = new ArrayList<>();
        List<Employee> employeesA = new ArrayList<>();
        employeesA.add(new Employee("1008", "Lucy1", 0, 24));
        employeesA.add(new Employee("1009", "Lucy2", 0, 24));
        List<Employee> employeesB = new ArrayList<>();
        employeesB.add(new Employee("1018", "Lily1", 1, 25));
        employeesB.add(new Employee("1019", "Lily2", 1, 25));
        employees.add(employeesA);
        employees.add(employeesB);
        // List<Employee> list1 = employees.stream().flatMap(StreamApiTest3::characterStream).collect(toList());
        List<Employee> list1 = employees.stream().flatMap(e -> characterStream(e)).collect(toList());
        /**
         * Employee{id='1008', name='Lucy1', sex=0, age=24}
         * Employee{id='1009', name='Lucy2', sex=0, age=24}
         * Employee{id='1018', name='Lily1', sex=1, age=25}
         * Employee{id='1019', name='Lily2', sex=1, age=25}
         */
        list1.forEach(System.out::println);
    }


    public static Stream<Employee> characterStream(List<Employee> employeeList) {
        List<Employee> result = new ArrayList<>();
        for (Employee e : employeeList) {
            result.add(e);
        }
        return result.stream();
    }

    public static Stream<Character> getCharacterByString(String str) {
        List<Character> characterList = new ArrayList<>();
        for (Character character : str.toCharArray()) {
            characterList.add(character);
        }
        return characterList.stream();
    }


    @Test
    public void test3() {
        List list1 = new ArrayList();
        list1.add(1);
        list1.add(2);
        list1.add(3);
        List list2 = new ArrayList();
        list2.add(4);
        list2.add(5);
        list2.add(6);
        //     list1.add(list2);
        System.out.println(list1);   //[1, 2, 3, [4, 5, 6]]
        list1.addAll(list2);
        System.out.println(list1); //[1, 2, 3, 4, 5, 6]
    }

    //排序 sorted
    @Test
    public void testSorted() {
        //sorted()--自然排序(Comparable)
        List<Integer> integers = Arrays.asList(12, 54, 6656, -232, 45, 0);
        integers.stream().sorted().forEach(i -> {
            //-232,0,12,45,54,6656,
            System.out.print(i + ",");
        });


//        sorted(Comparator com)--定制排序（Comparator）
        List<Employee> employees = Employee.getEmployees();
        employees.stream().sorted((e1, e2) -> Integer.compare(e1.getSex(), e2.getSex())).
                forEach(System.out::print);
    }


    //去重 distinct
    @Test
    public void testDistinct() {
        List<Integer> integers = Arrays.asList(1, 2, 3, 3, 4, 4, 5, 5);
        List<Integer> collect = integers.stream().distinct().collect(Collectors.toList());
        System.out.println(collect);//[1, 2, 3, 4, 5]
    }

    // peek与map功能差不多，就是peek没有返回值，map有返回值
    //peek是个中间操作，它提供了一种对流中所有元素操作的方法，
    // 而不会把这个流消费掉（foreach会把流消费掉），然后你可以继续对流进行其他操作。
    @Test
    public void testPeek() {
        //java8流中所有的操作都是蓄而不发的，只有执行foreach，collect等终结操作时，流的操作才会执行。
        Stream.of("first", "second", "three", "four").peek(e -> System.out.print(e+","));//不会有输出

        //first,second,three,four,
        Stream.of("first", "second", "three", "four").peek(e -> System.out.print(e+",")).collect(Collectors.toList());
    }
}
